/**
* @brief 操作系统内核头文件
* @author chenjl
* @date 2019.07.01
*/

/**
* 最大允许连续工作天数，5天。
* 必须保证至少有一个后台任务一直处理就绪状态
*/
#ifndef __KERNEL_H__
#define __KERNEL_H__

#include "kerOs.h"

#undef __FPU_USED
#define __FPU_USED 1

typedef enum {
    TASK_STATUS_INVALID,  ///<任务无效
    TASK_STATUS_READY,              ///<准备就绪，等待CPU时间
    TASK_STATUS_WAIT,               ///<等待某事件发生
    TASK_STATUS_RUNNING             ///<正在运行
}TASK_STATUS;

typedef struct {
    #if (__FPU_USED == 1)
    uint32  sm[16];
    #endif
    uint32  r4_r11[8];
    uint32  r0;
    uint32  r1;
    uint32  r2;
    uint32  r3;
    uint32  r12;
    uint32  lr;
    uint32  pc;
    uint32 xpsr;
    #if (__FPU_USED == 1)
    uint32  sa[16];
    uint32  fpscr;
    #endif
}EXCEPTION_CONTEXT;

typedef struct {
    uint32 r0;
    uint32 r1;
    uint32 r2;
    uint32 r3;
    uint32 r12;
    uint32 lr;
    uint32 pc;
    uint32 xpsr;
}SVC_CONTEXT;

typedef struct {
    /*加载保存的初始参数数据*/
    uint32 ram_start;       ///< RAM起始地址
    uint32 ram_size;        ///< RAM大小
    uint32 stack_size;
    uint32 rom_start;       ///<ROM 起始地址
    uint32 rom_size;        ///<ROM 大小
    int32  period;          ///<调度周期时间
    uint8  priority;        ///<优先级,0最高，255最低
    uint8  shmAttri;        ///<共享内存访问权限，0=RW,1=RO
    
    /*初始计算量*/
    uint32 stack_top;       ///< 加载时，自动计算的栈顶位置
    uint32 *stack_buttom;    ///< 加载时，自动计算的栈底，置标志用于检测栈溢出
    uint32 mpu_bar[8];      ///< MPU使用的RBAR数据
    uint32 mpu_asr[8];      ///< MPU使用的RASR数据
    /*任务状态*/
    TASK_STATUS status;
    int32  period_time;     ///<周期调度剩余时间
    int32  wait_time;       ///<超时等待时间
    uint32 timtick;         ///<上次计算时间雕花
    uint32 touchtick;       ///<上次调度时间
    uint32 stack_ptr;       ///<当前指针位置
}TASK_CONTEXT;

//栈底检测标志
#define     STACK_END_FLAG  (0xed01)

extern uint16 kerCpuIdleMill;

int32 Kernel_NextTask(void);
TASK_CONTEXT *Kernel_GetCurTask(void);
void kerSetIdleTaskMpu(void);
uint32 kerGetSystemTime(void);
uint32 KerGetSystemTick(void);
uint16 KerGetCpuIdle(void);

void kerTaskWait(uint32 ms);
void kerTaskWaitNxtPeriod(void);
void kerTaskDelay(uint32 us);
void kerTaskKill(void);

void kerActiveHighPrior(uint8 ckPri);

#endif
